package com.gmail.rusal4ica.logic;

/**
 * @author The Imperial Sword Team
 */


public class Board {
	private static final char DOT = '*';

	public static final char LINE_FIELD_DEFAULT = 'l';
	public static final char LINE_FIELD_HORIZONTAL = '-';
	public static final char LINE_FIELD_VERTICAL = '|';

	public static final char FIELD_EMPTY = 'w';

	public static final int BOARD_MIN_SIZE = 7;
	public static final int BOARD_MAX_SIZE = 11;
	public static final int BOARD_DEFAULT_SIZE = BOARD_MIN_SIZE;

	private int boardSizeN;
	private int boardSizeM;
	
	private char[][] board;

	public Board(){
		boardSizeN = BOARD_DEFAULT_SIZE;
		boardSizeM = BOARD_DEFAULT_SIZE;
		board = new char[this.boardSizeN][this.boardSizeM];
		fillBoard();		
	}

	public Board(int boardSizeN, int boardSizeM){
		setBoardSize(boardSizeN, boardSizeM);
		board = new char[this.boardSizeN][this.boardSizeM];
		fillBoard();
	}

	/**
	 * The method initializes the board with default values.
	 */
	private void fillBoard(){
		for (int i = 0; i < board.length; i ++) {
			for (int j = 0; j < board[0].length; j ++) {
				if(checkIndexForEven(i, j)){
					board[i][j] = DOT;
				}
				if(checkIndexesForOdd(i, j)){
					board[i][j] = FIELD_EMPTY;
				}
				if(!((checkIndexForEven(i, j) || checkIndexesForOdd(i, j)))){
					board[i][j] = LINE_FIELD_DEFAULT;
				}
			}
		}
	}

	/**
	 * The method returns the char at the given position on the board.
	 * 
	 * @param i - row coordinate for the char
	 * @param j - column coordinate for the char
	 * @return - the char
	 */
	public char getBoardCharAt(int i, int j){
		if(isRowIndexInRange(i) && isColumnIndexInRange(j)){
			return board[i][j];
		}
		throw new IndexOutOfBoundsException("Wrong parameters! Index out of bounds!");
	}

	/**
	 * The method checks the indexes for oddity.
	 * 
	 * @param i - row index
	 * @param j - column index
	 * @return - true or false
	 */
	private boolean checkIndexesForOdd(int i, int j) {
		return (i % 2 != 0) && (j % 2 != 0);
	}

	/**
	 * The method checks the indexes for evenness.
	 * 
	 * @param i - row index
	 * @param j - column index
	 * @return - true or false
	 */
	private boolean checkIndexForEven(int i, int j) {
		return (i % 2 == 0) && (j % 2 == 0);
	}

	/**
	 * The method calculates and sets the size of the board.
	 * 
	 * @param numEmptyFields - the number of empty fields needed on board
	 */
	private void setBoardSize(int numEmptyFieldsN, int numEmptyFieldsM){
		
		if(numEmptyFieldsN < BOARD_MIN_SIZE) {
			boardSizeN = BOARD_MIN_SIZE;
		} else {
			boardSizeN = numEmptyFieldsN;
		}
		
		if(numEmptyFieldsN > BOARD_MAX_SIZE) {
			boardSizeN = BOARD_MAX_SIZE;
		} else {
			boardSizeN = numEmptyFieldsN;
		}

		if(numEmptyFieldsM < BOARD_MIN_SIZE) {
			boardSizeM = BOARD_MIN_SIZE;
		} else {
			boardSizeM = numEmptyFieldsM;
		}
		
		if(numEmptyFieldsM > BOARD_MAX_SIZE) {
			boardSizeM = BOARD_MAX_SIZE;
		} else {
			boardSizeM = numEmptyFieldsM;
		}		
	}	

	/**
	 * The method checks if the row index is in range.
	 * 
	 * @param index - the index to check
	 * @return - true or false
	 */
	 public boolean isRowIndexInRange(int index){
		return (index >= 0) && (index < boardSizeN);
	}
	
	/**
	 * The method checks if the column index is in range.
	 * 
	 * @param index - the index to check
	 * @return - true or false
	 */
	public boolean isColumnIndexInRange(int index){
		return (index >= 0) && (index < boardSizeM);
	}

	public int getBoardSizeN(){
		return boardSizeN;
	}
	
	public int getBoardSizeM(){
		return boardSizeM;
	}

	public char[][] getBoard() {
		return board;
	}

}
